home *** CD-ROM | disk | FTP | other *** search
Text File | 1990-06-28 | 26.8 KB | 1,174 lines |
- Path: xanth!cs.odu.edu!Amiga-Request
- From: Amiga-Request@cs.odu.edu (Amiga Sources/Binaries Moderator)
- Newsgroups: comp.sources.amiga
- Subject: v90i188: UUCP 1.06D - UNIX compatible uucp/news/mail system, Part10/12
- Message-ID: <12979@xanth.cs.odu.edu>
- Date: 28 Jun 90 12:23:31 GMT
- Sender: news@cs.odu.edu
- Reply-To: Matt Dillon <@uunet.uu.net:overload!dillon>
- Lines: 1160
- Approved: tadguy@cs.odu.edu (Tad Guy)
- X-Mail-Submissions-To: Amiga@cs.odu.edu
- X-Post-Discussions-To: comp.sys.amiga
-
- Submitted-by: Matt Dillon <@uunet.uu.net:overload!dillon>
- Posting-number: Volume 90, Issue 188
- Archive-name: unix/uucp-1.06d/part10
-
- #!/bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 10 (of 12)."
- # Contents: uucp2/src/sendmail/sendmail.c
- # Wrapped by tadguy@xanth on Thu Jun 28 08:21:35 1990
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'uucp2/src/sendmail/sendmail.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'uucp2/src/sendmail/sendmail.c'\"
- else
- echo shar: Extracting \"'uucp2/src/sendmail/sendmail.c'\" \(24049 characters\)
- sed "s/^X//" >'uucp2/src/sendmail/sendmail.c' <<'END_OF_FILE'
- X
- X/*
- X * SENDMAIL / RMAIL
- X *
- X * $Header: Beta:src/uucp/src/sendmail/RCS/sendmail.c,v 1.1 90/02/02 12:15:01 dillon Exp Locker: dillon $
- X *
- X * (C) Copyright 1989-1990 by Matthew Dillon, All Rights Reserved.
- X *
- X * SENDMAIL <file -f from -t to -s subject -c cc -b bcc -r
- X * RMAIL user
- X *
- X * Example: Sendmail <datafile -froot
- X *
- X * From: line is automatically added but can be overriden by a From:
- X * header in the file. stdin is made up of a list of headers, a blank
- X * line, and then data until EOF.
- X *
- X * the -r option tells sendmail that this is incomming mail.
- X * If av[0] begins with an 'r' for RMail instead of an 's' for
- X * Sendmail, then the rmail argument format is used (rmail user),
- X * as well as forcing -r.
- X */
- X
- X#include "defs.h"
- X
- X#include <fcntl.h>
- X#include <log.h>
- X#include <time.h>
- X#include <pwd.h>
- X
- Xtypedef struct List LIST;
- Xtypedef struct Node NODE;
- X
- XIDENT(".06");
- X
- XLocal void Usage(void);
- XLocal int brk(void);
- XLocal NODE *MakeNode(LIST *, char *);
- XLocal void MakeToFixNode(LIST *, char *, char *);
- XLocal void fixCallBack(char *);
- XLocal void IntegrateHeader(char *, short);
- XLocal void FromFixup(LIST *);
- XLocal void ToFixup(LIST *);
- XLocal void MakeToAddrNode(LIST *, char *);
- XLocal FILE *SendMailTo(LIST *, FILE *);
- XLocal FILE *OneMailTo(char *, FILE *);
- XLocal FILE *OneMailToPipe(char *, FILE *);
- XLocal FILE *OneMailToUser(char *, FILE *);
- XLocal FILE *OneMailToFile(char *, FILE *);
- XLocal FILE *OneMailToUUCP(char *, char *, FILE *);
- XLocal void DumpHeaderInfo(FILE *, int, int, int);
- XLocal void DumpHeader(FILE *, char *, LIST *);
- XLocal NODE *FindHeader(char *);
- XLocal void DumpCombineHeader(FILE *, char *, LIST *);
- XLocal char *atime(time_t *);
- XLocal int GetHourOffset(char *);
- XLocal void PostPend(char *, int);
- XLocal int EmptyList(LIST *);
- X
- X
- X#define RCVR_UUCP 1
- X#define RCVR_SENDMAIL 2
- X
- Xchar *UserName;
- Xchar *RealName;
- Xchar *NodeName;
- Xchar *DomainName;
- Xchar *TimeZoneName; /* All caps, ex: PST */
- Xchar *DefaultNode; /* for addr formats we don't understand */
- XLIST RecvList; /* Received: */
- XLIST FromList; /* last one rules */
- XLIST ToList; /* To: */
- XLIST CcList; /* Cc: */
- XLIST BccList; /* Bcc: */
- XLIST XccList; /* list of actual mail to be sent */
- XLIST SubjList; /* Subject: */
- XLIST HdrList; /* other headers not specifically parsed */
- Xchar ScrBuf[1024];
- Xchar ScrBuf2[1024];
- Xchar TempFileBuf[256];
- Xint Seq; /* UUCP sequence no */
- Xchar Notify;
- Xchar ROpt; /* Receive-Mail flag */
- Xstatic char OrigFromLine[512];
- Xstatic char FromLine[512]; /* 'From ' line, if ROpt */
- X
- X
- X
- Xmain(ac, av)
- Xchar *av[];
- X{
- X short isRMail = 0;
- X short isSendMail = 1;
- X FILE *fi;
- X
- X onbreak(brk);
- X
- X NewList(&RecvList);
- X NewList(&FromList);
- X NewList(&ToList);
- X NewList(&CcList);
- X NewList(&BccList);
- X NewList(&XccList);
- X NewList(&SubjList);
- X NewList(&HdrList);
- X
- X UserName = GetUserName();
- X RealName = GetRealName();
- X
- X if (UserName == NULL) {
- X puts("Sendmail: UserName config entry not found!");
- X ulog(0, "UserName config missing");
- X exit(1);
- X }
- X if (RealName == NULL) {
- X puts("Sendmail: RealName config entry not found!");
- X ulog(0, "RealName config missing");
- X exit(1);
- X }
- X
- X NodeName = FindConfig("NodeName");
- X if (NodeName == NULL) {
- X puts("Sendmail: NodeName config entry not found!");
- X ulog(0, "NodeName config missing");
- X exit(1);
- X }
- X DomainName = FindConfig("DomainName");
- X if (DomainName == NULL) {
- X puts("Sendmail: DomainName config entry not found! using .UUCP");
- X DomainName = ".UUCP";
- X }
- X DefaultNode = FindConfig("DefaultNode");
- X TimeZoneName = FindConfig("TimeZone");
- X
- X LoadAliases();
- X
- X {
- X char *ptr = av[0] + strlen(av[0]);
- X
- X /*
- X * Skip path
- X */
- X
- X while (ptr >= av[0] && *ptr != ':' && *ptr != '/')
- X --ptr;
- X ++ptr;
- X
- X if (*ptr == 'r' || *ptr == 'R') {
- X isRMail = 1;
- X isSendMail = 0;
- X }
- X }
- X
- X if (isRMail) {
- X char *addr = (ac == 2) ? av[1] : "Mailer-Daemon";
- X
- X MakeNode(&BccList, addr);
- X UserName = "postmaster"; /* XXX */
- X RealName = "Mr.Amiga"; /* XXX */
- X ROpt = 1; /* no header processing */
- X }
- X if (isSendMail) {
- X short i;
- X char *arg;
- X for (i = 1; i < ac; ++i) {
- X arg = av[i];
- X if (*arg != '-')
- X Usage();
- X switch(arg[1]) {
- X case 'f':
- X UserName = av[i+1];
- X sprintf(ScrBuf, "%s@%s%s", UserName, NodeName, DomainName);
- X MakeNode(&FromList, ScrBuf);
- X ++i;
- X break;
- X case 'r':
- X RealName = av[++i];
- X break;
- X case 't':
- X MakeNode(&ToList, av[++i]);
- X break;
- X case 'c':
- X MakeNode(&CcList, av[++i]);
- X break;
- X case 'b':
- X MakeNode(&BccList, av[++i]);
- X break;
- X case 's':
- X MakeNode(&SubjList, av[++i]);
- X break;
- X case 'r':
- X ++ROpt;
- X break;
- X default:
- X Usage();
- X }
- X }
- X }
- X
- X /*
- X * Read headers from input file. Headers are not necessarily
- X * contained on a single line. Maximum 4096 chars per header.
- X */
- X
- X if (ROpt) {
- X fgets(ScrBuf, sizeof(ScrBuf), stdin);
- X strcpy(OrigFromLine, ScrBuf);
- X if (strncmp(ScrBuf, "From ", 5) != 0) {
- X ulog(-1, "Receive mail, expected 'From ', got %s", ScrBuf);
- X }
- X strcpy(FromLine, "From ");
- X PostPend(ScrBuf + 5, 1);
- X
- X while (fgets(ScrBuf, sizeof(ScrBuf), stdin) && strncmp(ScrBuf, ">From ", 6) == 0) {
- X strcpy(OrigFromLine, ScrBuf + 1);
- X PostPend(ScrBuf + 6, 1);
- X }
- X strcpy(ScrBuf2, OrigFromLine + 5);
- X PostPend(ScrBuf2, 0);
- X } else {
- X ScrBuf[0] = '\n';
- X fgets(ScrBuf, sizeof(ScrBuf), stdin);
- X }
- X {
- X static char Hdr[4096];
- X short i = 0; /* index into Hdr */
- X
- X while (ScrBuf[0] != '\n') {
- X char *ptr = ScrBuf;
- X while (*ptr && *ptr != ' ' && *ptr != 9 && *ptr != ':')
- X ++ptr;
- X if (*ptr == ':') { /* found new header */
- X if (i) /* Dump old header */
- X IntegrateHeader(Hdr, i);
- X strcpy(Hdr, ScrBuf);
- X i = strlen(Hdr);
- X } else { /* append to existing header */
- X if (i == 0)
- X puts("Expected a Header!");
- X strcpy(Hdr + i, ScrBuf);
- X i = i + strlen(Hdr + i);
- X }
- X
- X if (fgets(ScrBuf, sizeof(ScrBuf), stdin) == NULL)
- X ScrBuf[0] = '\n';
- X }
- X if (i)
- X IntegrateHeader(Hdr, i);
- X
- X if (ScrBuf[0] != '\n') {
- X puts("sendmail: no mail");
- X ulog(0, "No Mail");
- X exit(1);
- X }
- X }
- X
- X /*
- X * Parse & fixup each To:, Cc:, and Bcc: field.
- X *
- X * From: we add the personal info arg from the password file
- X * To: we expand any aliases
- X */
- X
- X if (ROpt == 0)
- X FromFixup(&FromList);
- X if (ROpt) {
- X ToFixup(&BccList);
- X } else {
- X ToFixup(&ToList);
- X ToFixup(&CcList);
- X ToFixup(&BccList);
- X }
- X
- X /*
- X * If no Subject: field add a dummy one
- X */
- X
- X if (EmptyList(&SubjList))
- X MakeNode(&SubjList, "");
- X
- X if (EmptyList(&FromList)) {
- X sprintf(ScrBuf, "%s@%s%s", UserName, NodeName, DomainName);
- X MakeNode(&FromList, ScrBuf);
- X }
- X
- X fi = SendMailTo(&XccList, stdin);
- X if (fi && fi != stdin)
- X fclose(fi);
- X if (TempFileBuf[0])
- X remove(TempFileBuf);
- X UnLockFiles();
- X
- X /*
- X * Notify if T:MailRdy does not exist (created by us, deleted by
- X * notify when notify exits). Prevents running multiple notifies.
- X */
- X
- X if (Notify) {
- X int fd = open("T:MailRdy", O_RDONLY);
- X if (fd < 0) {
- X char *cmd;
- X
- X
- X if (cmd = FindConfig(MAILREADYCMD)) {
- X fd = open("T:MailRdy", O_CREAT|O_TRUNC, 0666);
- X if (fd >= 0)
- X close(fd);
- X sprintf(ScrBuf, "Run %s -x T:MailRdy", cmd);
- X Execute(ScrBuf, NULL, NULL);
- X }
- X } else {
- X close(fd);
- X }
- X }
- X return(0);
- X}
- X
- Xvoid
- XUsage()
- X{
- X printf(
- X "Sendmail -f user [-t address -c address -b address -s subject -r]\n"
- X "RMail user\n"
- X );
- X}
- X
- Xint
- Xbrk()
- X{
- X return(0);
- X}
- X
- X/*
- X * Strips string and creates named node which is appended to the
- X * given list.
- X */
- X
- XNODE *
- XMakeNode(list, str)
- XLIST *list;
- Xchar *str;
- X{
- X NODE *node;
- X char *ptr;
- X
- X while (*str == ' ' || *str == 9)
- X ++str;
- X for (ptr = str + strlen(str); ptr >= str && (*ptr == ' ' || *ptr == 9); --ptr);
- X ++ptr;
- X *ptr = 0;
- X node = malloc(sizeof(NODE) + strlen(str) + 1);
- X node->ln_Name = (char *)(node + 1);
- X strcpy(node->ln_Name, str);
- X AddTail(list, node);
- X return(node);
- X}
- X
- X/*
- X *
- X */
- X
- Xvoid
- XMakeToFixNode(list, str, send)
- XLIST *list;
- Xchar *str;
- Xchar *send;
- X{
- X char *ptr;
- X short len;
- X short c;
- X void fixCallBack();
- X
- X while (str < send && (*str == ' ' || *str == 9))
- X ++str;
- X for (ptr = send - 1; ptr >= str && (*ptr == ' ' || *ptr == 9); --ptr);
- X ++ptr;
- X
- X len = ptr - str;
- X if (len < 0)
- X return;
- X
- X /*
- X * str[0..len-1]
- X */
- X
- X c = str[len];
- X str[len] = 0;
- X
- X if (ROpt) { /* disallow remote asking for special options */
- X ulog(-1, "Received mail for %s", str);
- X if (str[0] == '>' || str[0] == '<' || str[0] == '|' || str[0] == ':' || str[0] == '/') {
- X ulog(-1, "SendMail, bad user %s", str);
- X return;
- X }
- X }
- X
- X {
- X NODE *node = malloc(sizeof(NODE) + strlen(str) + 1);
- X
- X node->ln_Name = (char *)(node + 1);
- X strcpy(node->ln_Name, str);
- X AddTail(list, node);
- X }
- X
- X UserAliasList(str, fixCallBack); /* from lib/alias.c */
- X str[len] = c;
- X}
- X
- Xvoid
- XfixCallBack(user)
- Xchar *user;
- X{
- X NODE *node;
- X
- X if (user[0] == '<') {
- X FILE *fi = fopen(user + 1, "r");
- X char *buf = malloc(256);
- X
- X if (fi == NULL) {
- X ulog(-1, "Unable to open < file %s", user + 1);
- X return;
- X }
- X while (fgets(buf, 256, fi)) {
- X short i = 0;
- X short j;
- X while (buf[i] == ' ' || buf[i] == 9)
- X ++i;
- X if (buf[i] == 0 || buf[i] == '\n')
- X continue;
- X for (j = i; buf[j] && buf[j] != '\n' && buf[j] != ' ' && buf[j] != 9; ++j);
- X buf[j] = 0;
- X UserAliasList(buf, fixCallBack);
- X }
- X fclose(fi);
- X free(buf);
- X return;
- X }
- X
- X ulog(-1, "Sendmail, Sending mail to %s", user);
- X
- X if (user[0] == '\\')
- X ++user;
- X
- X node = malloc(sizeof(NODE) + strlen(user) + 1);
- X node->ln_Name = (char *)(node + 1);
- X strcpy(node->ln_Name, user);
- X AddTail(&XccList, node);
- X}
- X
- X
- X/*
- X * Integrates a header
- X */
- X
- Xvoid
- XIntegrateHeader(hdr, len)
- Xchar *hdr;
- Xshort len;
- X{
- X if (hdr[len-1] == '\n') /* strip trailing newline */
- X hdr[len-1] = 0;
- X
- X if (strncmp(hdr, "From:", 5) == 0) {
- X MakeNode(&FromList, hdr + 5);
- X return;
- X }
- X if (strncmp(hdr, "To:", 3) == 0) {
- X MakeNode(&ToList, hdr + 3);
- X return;
- X }
- X if (strncmp(hdr, "Cc:", 3) == 0) {
- X MakeNode(&CcList, hdr + 3);
- X return;
- X }
- X if (strncmp(hdr, "Bcc:", 4) == 0) {
- X MakeNode(&BccList, hdr + 4);
- X return;
- X }
- X if (strncmp(hdr, "Subject:", 8) == 0) {
- X MakeNode(&SubjList, hdr + 8);
- X return;
- X }
- X if (strncmp(hdr, "Received:", 9) == 0) {
- X MakeNode(&RecvList, hdr + 9);
- X return;
- X }
- X MakeNode(&HdrList, hdr);
- X}
- X
- X/*
- X * Adds (personal info) to FromList based on passwd entry or, if
- X * that is not available, from the Config entry 'RealName' or
- X * ENV:REALNAME (env:REALNAME takes precedence)
- X */
- X
- Xvoid
- XFromFixup(list)
- XLIST *list;
- X{
- X NODE *node;
- X NODE *nn;
- X LIST tmpList;
- X
- X NewList(&tmpList);
- X
- X while (node = RemHead(list)) {
- X /*
- X * FIXME. Fix getpwnam() and use pw_gecos entry.
- X */
- X nn = malloc(sizeof(NODE) + strlen(node->ln_Name) + strlen(RealName) + 16);
- X nn->ln_Name = (char *)(nn + 1);
- X sprintf(nn->ln_Name, "%s (%s)", node->ln_Name, RealName);
- X free(node);
- X AddTail(&tmpList, nn);
- X }
- X while (node = RemHead(&tmpList))
- X AddTail(list, node);
- X}
- X
- X/*
- X * Converts an unparsed list of names into a list of single address
- X * fields, removing any personal idents from the entries. These will
- X * be recombined after processing when the data file is written out.
- X *
- X * Also expands sendmail aliases (UULIB:Aliases) (HACK)
- X */
- X
- Xvoid
- XToFixup(list)
- XLIST *list;
- X{
- X NODE *node;
- X LIST tmpList;
- X
- X NewList(&tmpList);
- X
- X while (node = RemHead(list)) {
- X char *str = node->ln_Name;
- X char *ptr;
- X
- X while (*str) { /* breakup fields by newline or comma */
- X for (ptr = str; *ptr && *ptr != '\n' && *ptr != ','; ++ptr);
- X MakeToAddrNode(&tmpList, str);
- X str = ptr;
- X while (*str == '\n' || *str == ',' || *str == ' ' || *str == 9)
- X ++str;
- X }
- X free(node);
- X }
- X while (node = RemHead(&tmpList))
- X AddTail(list, node);
- X}
- X
- X/*
- X * Extracts a single name / address (comma or newline delimited)
- X * field and creates a new node.
- X */
- X
- Xvoid
- XMakeToAddrNode(list, str)
- XLIST *list;
- Xchar *str;
- X{
- X char *p1, *p2;
- X short ns = 0; /* non-whitespace encountered */
- X
- X for (p1 = str; *p1 && *p1 != ',' && *p1 != '\n'; ++p1) {
- X if (*p1 == '(') { /* addr (name) OR (name) addr */
- X if (ns) { /* addr (name) */
- X MakeToFixNode(list, str, p1);
- X } else {
- X while (*p1 && *p1 != ',' && *p1 != '\n' && *p1 != ')')
- X ++p1;
- X if (*p1 == ')') {
- X for (p2 = p1 + 1; *p2 && *p2 != ',' && *p2 != '\n'; ++p2);
- X MakeToFixNode(list, p1 + 1, p2);
- X }
- X }
- X return;
- X }
- X
- X if (*p1 == '<') { /* <addr> */
- X for (p2 = p1 + 1; *p2 && *p2 != ',' && *p2 != '\n' && *p2 != '>'; ++p2);
- X if (*p2 == '>')
- X MakeToFixNode(list, p1 + 1, p2);
- X return;
- X }
- X if (*p1 != ' ' && *p1 != 9)
- X ns = 1;
- X }
- X MakeToFixNode(list, str, p1);
- X}
- X
- X
- X/*
- X * Send mail to <recipeant>
- X *
- X * -Local mail
- X * -Machine path (UUCP)
- X */
- X
- XFILE *
- XSendMailTo(list, fi)
- XLIST *list;
- XFILE *fi;
- X{
- X NODE *node;
- X
- X for (node = list->lh_Head; node != (NODE *)&list->lh_Tail; node = node->ln_Succ)
- X fi = OneMailTo(node->ln_Name, fi);
- X return(fi);
- X}
- X
- XFILE *
- XOneMailTo(toaddr, rfi)
- Xchar *toaddr;
- XFILE *rfi;
- X{
- X short i;
- X char c;
- X static char ToAddr[512];
- X static char Buf[512];
- X static char typeBuf[16];
- X static char classBuf[16];
- X static char addrBuf[128];
- X
- X if (toaddr[0] == '|') /* pipe through command */
- X return(OneMailToPipe(toaddr + 1, rfi));
- X if (toaddr[0] == '>') /* copy to file */
- X return(OneMailToFile(toaddr + 1, rfi));
- X
- X strncpy(ToAddr, toaddr, sizeof(ToAddr));
- X ToAddr[sizeof(ToAddr) - 1] = 0;
- X
- Xloop:
- X for (i = 0; c = ToAddr[i]; ++i) {
- X if (c == '!' || c == '%' || c == '@' || c == ':')
- X break;
- X }
- X if (c == 0) /* local name */
- X return(OneMailToUser(ToAddr, rfi));
- X
- X /*
- X * Non-Local mail
- X */
- X
- X i = ParseAddress(ToAddr, Buf, strlen(ToAddr));
- X if (DomainLookup(Buf, strlen(Buf), typeBuf, classBuf, addrBuf)) {
- X printf("type %s class %s addr %s\n", typeBuf, classBuf, addrBuf);
- X printf("buf %s\n", Buf);
- X
- X /*
- X * Note distinction between mail destination and mail forwarder.
- X * mail destination removes the first machine from the rmail line
- X * mail forwarder does NOT
- X */
- X
- X if (strcmpi(classBuf, "UU") == 0) {
- X if (strcmpi(typeBuf, "MD") == 0)
- X return(OneMailToUUCP(addrBuf, Buf + i + 1, rfi));
- X else
- X return(OneMailToUUCP(addrBuf, Buf, rfi));
- X } else if (strcmpi(classBuf, "LL") == 0) { /* local mail, loop */
- X for (i = 0; Buf[i] && Buf[i] != '!'; ++i);
- X if (Buf[i] == 0) {
- X strcpy(Buf + i, "postmaster");
- X --i;
- X }
- X strcpy(ToAddr, Buf + i + 1);
- X goto loop;
- X } else {
- X ulog(-1, "Unsupported domain class: %s", classBuf);
- X printf("Unsupported domain class: %s\n", classBuf);
- X }
- X return(rfi);
- X } else {
- X ulog(-1, "Could not find domain for %s, no mail sent", Buf);
- X printf("Unable to send mail to %s\n", Buf);
- X return(rfi);
- X }
- X}
- X
- X
- XFILE *
- XOneMailToPipe(toaddr, rfi)
- Xchar *toaddr;
- XFILE *rfi;
- X{
- X FILE *fi;
- X char *ptr;
- X static long pos;
- X
- X if (TempFileBuf[0] == 0) {
- X strcpy(TempFileBuf, TmpFileName("T:pipe"));
- X fi = fopen(TempFileBuf, "w");
- X if (fi == NULL) {
- X ulog(-1, "Unable to open temp file %s for command: %s", TempFileBuf, toaddr);
- X return(rfi);
- X }
- X DumpHeaderInfo(fi, RCVR_SENDMAIL, 0, 1);
- X pos = ftell(fi);
- X while (fgets(ScrBuf, sizeof(ScrBuf), rfi))
- X fputs(ScrBuf, fi);
- X fclose(fi);
- X }
- X strcpy(ScrBuf, toaddr);
- X
- X ptr = toaddr;
- X if (strncmpi(toaddr, "run", 3) == 0) {
- X ptr += 3;
- X while (*ptr == ' ' || *ptr == 9)
- X ++ptr;
- X }
- X while (*ptr && *ptr != ' ' && *ptr != 9)
- X ++ptr;
- X
- X if (*ptr == 0)
- X strcat(ScrBuf, " ");
- X sprintf(ScrBuf + (ptr - toaddr + 1), "<%s %s", TempFileBuf, ptr);
- X if (Execute(ScrBuf, NULL, NULL) == 0)
- X ulog(-1, "Couldn't execute %s", ScrBuf);
- X
- X fi = fopen(TempFileBuf, "r");
- X if (fi) {
- X if (rfi != stdin)
- X fclose(rfi);
- X rfi = fi;
- X fseek(rfi, pos, 0);
- X } else {
- X ulog(-1, "Couldn't reopen temp '%s', mail failed!", TempFileBuf);
- X rfi = stdin;
- X }
- X return(rfi);
- X}
- X
- XFILE *
- XOneMailToUser(toaddr, rfi)
- Xchar *toaddr;
- XFILE *rfi;
- X{
- X ++Notify;
- X strcpy(ScrBuf, MakeConfigPath(UUMAIL, toaddr));
- X return(OneMailToFile(ScrBuf, rfi));
- X}
- X
- XFILE *
- XOneMailToFile(tofile, rfi)
- Xchar *tofile;
- XFILE *rfi;
- X{
- X FILE *fo;
- X static char DataFile[128];
- X long pos;
- X
- X strcpy(DataFile, tofile);
- X
- X LockFile(DataFile);
- X fo = fopen(DataFile, "a");
- X if (fo == NULL) {
- X strcpy(DataFile, "T:MailOverflow");
- X fo = fopen(DataFile, "a");
- X if (fo)
- X ulog(-1, "Could not append to %s, appending to %s", tofile, DataFile);
- X else
- X ulog(-1, "Can't append to anywhere! (%s)", tofile);
- X }
- X if (fo) {
- X DumpHeaderInfo(fo, RCVR_SENDMAIL, 0, 1);
- X pos = ftell(fo);
- X if (ROpt) {
- X if (fgets(ScrBuf, sizeof(ScrBuf), rfi))
- X fputs(ScrBuf, fo);
- X }
- X while (fgets(ScrBuf, sizeof(ScrBuf), rfi)) {
- X if (ScrBuf[0] == 'F' && strncmp(ScrBuf, "From ", 5) == 0)
- X strins(ScrBuf, " ");
- X fputs(ScrBuf, fo);
- X }
- X fclose(fo);
- X if (rfi != stdin)
- X fclose(rfi);
- X rfi = fopen(DataFile, "r");
- X fseek(rfi, pos, 0);
- X }
- X UnLockFile(DataFile);
- X return(rfi);
- X}
- X
- XFILE *
- XOneMailToUUCP(toaddr, skipaddr, rfi)
- Xchar *toaddr;
- Xchar *skipaddr;
- XFILE *rfi;
- X{
- X static char ExecFile[128];
- X static char XExecFile[128];
- X static char CommandFile[128];
- X static char DataFile[128];
- X static char DestNode[256];
- X /*static char ToAddr[256];*/
- X FILE *fi;
- X int seq;
- X long pos;
- X short i;
- X short ai;
- X char *spoolDir = strdup(MakeConfigPath(UUSPOOL, ""));
- X
- X /*
- X * If the destination node
- X */
- X
- X strcpy(DestNode, toaddr);
- X
- X ai = -1;
- X for (i = 0; DestNode[i]; ++i) {
- X /*
- X * Remember index for additional paths
- X */
- X
- X if (DestNode[i] == '!') {
- X DestNode[i] = 0;
- X ai = i + 1;
- X break;
- X }
- X
- X /*
- X * Cut off machine name at 7 chars and ignore any domain
- X * info.
- X */
- X
- X if (i == 7 || DestNode[i] == '.')
- X DestNode[i] = 0;
- X }
- X
- X Seq = seq = GetSequence(4);
- X
- X#define FOFF strlen(spoolDir)
- X
- X sprintf(ExecFile, "%sD.%sX%04d", spoolDir, DestNode, seq++);
- X sprintf(XExecFile, "%sX.%sX%04d", spoolDir, DestNode, seq++);
- X sprintf(CommandFile,"%sC.%sA%04d", spoolDir, DestNode, seq++);
- X sprintf(DataFile, "%sD.%sB%04d", spoolDir, DestNode, seq);
- X
- X LockFile(CommandFile);
- X LockFile(DataFile);
- X
- X /*
- X * Note, cannot run uuxqt from sendmail as uuxqt may call
- X * sendmail!
- X */
- X
- X if (strncmp(DestNode, NodeName, 7) == 0)
- X fi = fopen(XExecFile, "w");
- X else
- X fi = fopen(ExecFile, "w");
- X
- X if (fi == NULL)
- X goto fail;
- X
- X fprintf(fi, "U %s\n", UserName);
- X fprintf(fi, "F %s\n", DataFile + FOFF);
- X fprintf(fi, "I %s\n", DataFile + FOFF);
- X if (ai >= 0)
- X fprintf(fi, "C rmail %s!%s\n", DestNode + ai, skipaddr);
- X else
- X fprintf(fi, "C rmail %s\n", skipaddr);
- X fclose(fi);
- X
- X if (strncmp(DestNode, NodeName, 7)) {
- X fi = fopen(CommandFile, "w");
- X if (fi == NULL)
- X goto fail;
- X
- X fprintf(fi, "S %s %s %s - %s 0666\n", DataFile + FOFF, DataFile + FOFF, UserName, DataFile + FOFF);
- X fprintf(fi, "S %s %s %s - %s 0666\n", ExecFile + FOFF, XExecFile + FOFF, UserName, ExecFile + FOFF);
- X fclose(fi);
- X }
- X
- X fi = fopen(DataFile, "w");
- X if (fi == NULL)
- X goto fail;
- X
- X DumpHeaderInfo(fi, RCVR_UUCP, 1, 0);
- X pos = ftell(fi);
- X
- X if (ROpt) {
- X if (fgets(ScrBuf, sizeof(ScrBuf), rfi))
- X fputs(ScrBuf, fi);
- X }
- X while (fgets(ScrBuf, sizeof(ScrBuf), rfi)) {
- X if (ScrBuf[0] == 'F' && strncmp(ScrBuf, "From ", 5) == 0)
- X strins(ScrBuf, " ");
- X fputs(ScrBuf, fi);
- X }
- X fclose(fi);
- X if (rfi != stdin)
- X fclose(rfi);
- X fi = fopen(DataFile, "r");
- X fseek(fi, pos, 0);
- X
- X UnLockFile(CommandFile);
- X UnLockFile(DataFile);
- X
- X free(spoolDir);
- X
- X return(fi);
- Xfail:
- X UnLockFile(CommandFile);
- X UnLockFile(DataFile);
- X
- X free(spoolDir);
- X puts("Fail");
- X ulog(-1, "Output failed %s", CommandFile);
- X return(rfi);
- X}
- X
- Xvoid
- XDumpHeaderInfo(fi, rcvr, resend, local)
- XFILE *fi;
- Xint rcvr, resend, local;
- X{
- X char *source;
- X time_t t;
- X
- X time(&t);
- X
- X /*
- X * Write header info
- X */
- X
- X if (rcvr == RCVR_UUCP)
- X source = "AmigaUUCP";
- X else
- X source = "Sendmail";
- X
- X if (ROpt) {
- X if (resend)
- X fprintf(fi, "%s %s remote from %s\n", FromLine, atime(&t), NodeName);
- X else
- X fprintf(fi, "%s %s\n", FromLine, atime(&t));
- X } else {
- X if (local)
- X fprintf(fi, "From %s %s\n", UserName, atime(&t));
- X else
- X fprintf(fi, "From %s %s remote from %s\n", UserName, atime(&t), NodeName);
- X }
- X fprintf(fi, "Received: by %s%s (1.05D/Amiga)\n\tid AA%05d; %s\n",
- X NodeName, DomainName, Seq, atime(&t)
- X );
- X DumpHeader(fi, "Received:", &RecvList);
- X if (ROpt == 0) {
- X time_t t2 = t + 3600 * GetHourOffset(TimeZoneName);
- X struct tm *ut;
- X
- X if (FindHeader("Date:") == NULL)
- X fprintf(fi, "Date: %s\n", atime(&t));
- X ut = localtime(&t2);
- X fprintf(fi, "Message-Id: <%02d%02d%02d%02d%02d.AA%05d@%s%s>\n",
- X ut->tm_year % 100, ut->tm_mon + 1, ut->tm_mday, ut->tm_hour, ut->tm_min,
- X Seq, NodeName, DomainName
- X );
- X }
- X
- X /*
- X * From:, To:, Cc:, Subject: (Bcc: never written to header),
- X * and any other header fields
- X */
- X
- X DumpHeader(fi, NULL, &HdrList);
- X DumpHeader(fi, "From:", &FromList);
- X DumpCombineHeader(fi, "To:", &ToList);
- X if (!EmptyList(&CcList))
- X DumpCombineHeader(fi, "Cc:", &CcList);
- X DumpHeader(fi, "Subject:", &SubjList);
- X
- X fprintf(fi, "\n");
- X}
- X
- Xvoid
- XDumpHeader(fi, field, list)
- XFILE *fi;
- Xchar *field;
- XLIST *list;
- X{
- X NODE *node;
- X
- X for (node = list->lh_Head; node != (NODE *)&list->lh_Tail; node = node->ln_Succ) {
- X if (field)
- X fprintf(fi, "%s %s\n", field, node->ln_Name);
- X else
- X fprintf(fi, "%s\n", node->ln_Name);
- X }
- X}
- X
- XNODE *
- XFindHeader(field)
- Xchar *field;
- X{
- X NODE *node;
- X short len = strlen(field);
- X
- X for (node = HdrList.lh_Head; node != (NODE *)&HdrList.lh_Tail; node = node->ln_Succ) {
- X if (strncmp(node->ln_Name, field, len) == 0)
- X return(node);
- X }
- X return(NULL);
- X}
- X
- Xvoid
- XDumpCombineHeader(fi, field, list)
- XFILE *fi;
- Xchar *field;
- XLIST *list;
- X{
- X NODE *node;
- X short ci = 0;
- X
- X fprintf(fi, "%s ", field);
- X for (node = list->lh_Head; node != (NODE *)&list->lh_Tail; node = node->ln_Succ) {
- X if (ci && ci + strlen(node->ln_Name) > 70) {
- X fprintf(fi, ",\n\t");
- X ci = 0;
- X }
- X if (ci)
- X fprintf(fi, ", ");
- X fprintf(fi, "%s", node->ln_Name);
- X ci += strlen(node->ln_Name) + 2;
- X }
- X fprintf(fi, "\n");
- X}
- X
- Xchar *
- Xatime(pt)
- Xtime_t *pt;
- X{
- X static char buf[40];
- X static char *mo[12] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
- X "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
- X };
- X static char *dow[7] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
- X struct tm *ut = localtime(pt);
- X
- X sprintf(buf, "%s, %d %s %02d %02d:%02d:%02d %s",
- X dow[ut->tm_wday], ut->tm_mday, mo[ut->tm_mon],
- X ut->tm_year % 100, ut->tm_hour, ut->tm_min, ut->tm_sec,
- X TimeZoneName
- X );
- X return(buf);
- X}
- X
- Xint
- XGetHourOffset(tz)
- Xchar *tz;
- X{
- X short i;
- X
- X static struct {
- X char *Name;
- X short Hours;
- X } TZAry[] = {
- X "GMT", 0,
- X "UT", 0,
- X "PST", 8,
- X "MST", 7,
- X "CST", 6,
- X "EST", 5,
- X "AST", 4,
- X "PDT", 7,
- X "MDT", 6,
- X "CDT", 5,
- X "EDT", 4,
- X "ADT", 3,
- X NULL, 0
- X };
- X for (i = 0; TZAry[i].Name; ++i) {
- X if (strncmp(tz, TZAry[i].Name, 3) == 0)
- X return((int)TZAry[i].Hours);
- X }
- X ulog(-1, "Unknown Timezone: %s", tz);
- X printf("Unknown Timezone: %s", tz);
- X return(6);
- X}
- X
- Xvoid
- XPostPend(str, frend)
- Xchar *str;
- Xint frend;
- X{
- X char *ptr;
- X if (frend) {
- X ptr = str + strlen(str);
- X while (ptr > str && *ptr != ' ' && *ptr != 9) {
- X if (*ptr == '\n')
- X *ptr = 0;
- X --ptr;
- X }
- X str = ptr + 1;
- X }
- X for (ptr = str; *ptr && *ptr != ' ' && *ptr != 9 && *ptr != '\n'; ++ptr);
- X if (frend)
- X *ptr++ = '!';
- X *ptr = 0;
- X for (ptr = FromLine + 5; *ptr && *ptr != ' ' && *ptr != 9; ++ptr);
- X strins(ptr, str);
- X}
- X
- XEmptyList(list)
- XLIST *list;
- X{
- X if (list->lh_Head == (NODE *)&list->lh_Tail)
- X return(1);
- X return(0);
- X}
- X
- END_OF_FILE
- if test 24049 -ne `wc -c <'uucp2/src/sendmail/sendmail.c'`; then
- echo shar: \"'uucp2/src/sendmail/sendmail.c'\" unpacked with wrong size!
- fi
- # end of 'uucp2/src/sendmail/sendmail.c'
- fi
- echo shar: End of archive 10 \(of 12\).
- cp /dev/null ark10isdone
- MISSING=""
- for I in 1 2 3 4 5 6 7 8 9 10 11 12 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 12 archives.
- rm -f ark[1-9]isdone ark[1-9][0-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
- --
- Mail submissions (sources or binaries) to <amiga@cs.odu.edu>.
- Mail comments to the moderator at <amiga-request@cs.odu.edu>.
- Post requests for sources, and general discussion to comp.sys.amiga.
-